package com.unicom.microserv.cs.ccc.online.wx.mq.rest;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.context.request.async.WebAsyncTask;

import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentLinkedDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 描    述:异步测试
 * 创建时间: 2019/01/07
 */
@RestController
public class AsyncTest {

    private ConcurrentLinkedDeque<DeferredResult<String>> deferredResults =
            new ConcurrentLinkedDeque<DeferredResult<String>>();


    @RequestMapping("/getResult")
    public DeferredResult<String> getDeferredResultController(){

        //设置 5秒就会超时
        final DeferredResult<String> stringDeferredResult = new DeferredResult<String>(Long.valueOf(1000));

        //将请求加入到队列中
        deferredResults.add(stringDeferredResult);

        final String message = "{username:wangbinghua}";

        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.submit(new Runnable() {
            @Override
            public void run() {

                try {
                    Thread.sleep(1010);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //业务处理
                System.out.println("业务处理");
                stringDeferredResult.setResult(message);
            }
        });


        //setResult完毕之后，调用该方法
        stringDeferredResult.onCompletion(new Runnable() {
            @Override
            public void run() {
                System.out.println("异步调用完成");
                //响应完毕之后，将请求从队列中去除掉
                deferredResults.remove(stringDeferredResult);
            }
        });

        stringDeferredResult.onTimeout(new Runnable() {
            @Override
            public void run() {
                System.out.println("业务处理超时");
                stringDeferredResult.setResult("error:timeOut");
            }
        });

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        stringDeferredResult.setResult("test");

        return stringDeferredResult;
    }

    //开启线程定时扫描队列，响应客户端
    @Scheduled(fixedRate = 1000)
    public void scheduleResult(){
        System.out.println(new Date());
        for(int i = 0;i < deferredResults.size();i++){
            DeferredResult<String> deferredResult = deferredResults.getFirst();
            deferredResult.setResult("result:" + i);
        }
    }

    @RequestMapping("/async")
    public WebAsyncTask<String> asyncTask(){

        // 1000 为超时设置
        WebAsyncTask<String> webAsyncTask = new WebAsyncTask<String>(6000,new Callable<String>(){

            @Override
            public String call() throws Exception {
                //业务逻辑处理
                Thread.sleep(5000);
                String message = "username:wangbinghua";
                return message;
            }
        });
        webAsyncTask.onCompletion(new Runnable() {
            @Override
            public void run() {
                System.out.println("调用完成");
            }
        });

        webAsyncTask.onTimeout(new Callable<String>() {
            @Override
            public String call() throws Exception {
                System.out.println("业务处理超时");
                return "<h1>Time Out</h1>";
            }
        });

        return webAsyncTask;
    }
}